class Overlays{
    constructor(){
        this.W = 0; 
        this.doseCircles = []; // [[circle, color, infowindows], ...]
        this.thermalCircles = [];
        this.pressureCircles = [];
        this.falloutPolygons = [];
        this.fireballCircle = [];
        
        this.doseInfo = {
            // rem: 中文名，雷姆，是剂量当量的单位。现已被Sv(希沃特)取代，1 rem = 0.01 Sv。
            // [title, message, color]
            '100': ['此距离处早期电离辐射剂量为：1Sv。', '此剂量会诱发疾病，造成的60天内死亡几率低于 5%；3% 的幸存者会因接触而死于癌症。'],
            '500': ['此距离处早期电离辐射剂量为：5Sv。', '此剂量可能会导致约1个月内死亡；15% 的幸存者最终会因辐射而死于癌症。'],
            '600': ['此距离处早期电离辐射剂量为：6Sv。', '此剂量可能会导致约1个月内死亡；18% 的幸存者最终会因辐射而死于癌症。'],
            '1000': ['此距离处早期电离辐射剂量为：10Sv。', '此剂量致命，受照者5分钟内丧失能力，有恢复期，会在4至6天内死亡。'],
            '5000': ['此距离处早期电离辐射剂量为：50Sv。', '此剂量致命，受照者5分钟内丧失能力，有恢复期，会在4至6天内死亡。'],
            'other': ['', ''],
        };
        this.thermalInfo = {
            '1st-100': ['此距离处造成一度烧伤。', '一度烧伤又称红斑性烧伤，仅伤及表皮的一部分。常于3～5天内愈合，不留瘢痕。'],
            '2nd-100': ['此距离处造成二度烧伤。', '二度烧伤是对皮肤的较深烧伤。会导致强烈的疼痛，需要几周时间才能痊愈。严重的二度烧伤会产生疤痕或需要移植。'],
            '3rd-100': ['此距离处造成三度烧伤。', '三度烧伤一般指全程皮肤的烧伤，因为疼痛神经受到破坏通常是无痛的。三度烧伤会造成严重的疤痕或残疾，并可能需要截肢。'],
            'noharm-100': ['此距离之外不会受到烧伤。', ''],
            '35': ['此距离处干燥的木材会被引燃。', ''],
            'other': ['', '']
        };
        this.pressureInfo = {
            '1': ['此距离处最大超压大小为：' + (1*psi2atm).toFixed(2) + 'atm。', '此压强下，玻璃窗可能会破裂。周围人群可能会在看到核爆炸的闪光（比压力波传播得更快）后来到窗户前而受到伤害。通常用作城市中光损害的基准。'],
            '5': ['此距离处最大超压大小为：' + (5*psi2atm).toFixed(2) + 'atm。', '此压强下，大多数住宅楼都会倒塌，受伤和死亡普遍可见。商业和住宅破坏中起火的几率很高，并且有很高的火势蔓延的风险。常常被用作城市中度破坏的基准。'],
            '20': ['此距离处最大超压大小为：' + (20*psi2atm).toFixed(2) + 'atm。', '此压强下，大量建造的混凝土建筑被严重损坏或拆毁；死亡率接近100%。常常被用作城市中严重破坏的基准。'],
            '200': ['此距离处最大超压大小为：' + (200*psi2atm).toFixed(2) + 'atm。', '此压强下，会对所有民用结构造成极大破坏，甚至对“硬化”结构造成一些破坏。'],
            '3000': ['此距离处最大超压大小为：' + (3000*psi2atm).toFixed(2) + 'atm。', '此压强下，绝大多数建筑难以承受此压力。'],
            'other': ['', '']
        };
        // this.falloutInfo = {
        //     // rad, 拉德，辐射吸收剂量的专用单位。从1986年起用SI导出单位Gy(戈〔瑞〕)取代。1rad=10-2Gy。
        //     '1': ['剂量率：0.01Gy/h。', ''],
        //     '10': ['剂量率：0.1Gy/h。', ''],
        //     '100': ['剂量率：1Gy/h.', ''],
        //     '1000': ['剂量率：10Gy/h', ''],
        // };
        this.fireballInfo = ['为核爆炸产生的火球最大尺寸', '火球内包含放射性物质，与地面接触时放射性沉降物的量将显著增加。在地面上几乎不产生放射性落尘的爆炸高度为：'];
    }

    init(burstyield){
        this.W = burstyield;
        if(debug) console.log("overlays, W", this.W)
        this.clear();
    }

    clear(){
        this.doseCircles = [];
        this.thermalCircles = [];
        this.pressureCircles = [];
        this.falloutPolygons = [];
        this.fireballCircle = [];
        map.clearOverlays();
    }

    clearFallout(){
        for(let i = 0; i < this.falloutPolygons.length;  i++){
            map.removeOverlay(this.falloutPolygons[i][0]);
        }
        this.falloutPolygons = [];
    }

    getCircle(p, r, type, value, extraInfo='', isOther=false, opt=''){
    // value 通常为从网页输入的值，是字符串类型
        let circle;
        let message = '<div style="margin-top: 0.2rem; marginleft: 0.5rem; font-size: 0.9rem">' + '距爆心地面距离：' + r.toFixed(2) + 'm。';
        let infoTitle = '';
        let color;
        switch(type){
            case 'dose':
                if(isOther){
                    infoTitle = extraInfo;
                    message += '';
                    color = this.getGradientColor(type, parseFloat(value));
                }
                else{
                    infoTitle = this.doseInfo[value][0];
                    message += this.doseInfo[value][1];
                    color = this.getGradientColor(type, parseFloat(value));
                }
                circle = new BMap.Circle(p, r,{
                    strokeWeight: 1,
                    strokeColor: color,
                    fillColor: color,
                    fillOpacity: 0.1
                });
                message += '</div>';
                var infowindow = new BMap.InfoWindow(message, {
                    width : 300,     // 信息窗口宽度
                    height: 100,     // 信息窗口高度
                    title : infoTitle , // 信息窗口标题
                });
                this.doseCircles.push([circle, color, infowindow]);
                break;
            case 'thermal':
                if(isOther){
                    infoTitle = extraInfo;
                    message += '';
                    color = this.getGradientColor('thermal', opt);
                }
                else{
                    infoTitle = this.thermalInfo[value][0];
                    message += this.thermalInfo[value][1] + extraInfo;
                    color = this.getGradientColor('thermal', opt);
                }
                circle = new BMap.Circle(p, r,{
                    strokeWeight: 1,
                    strokeColor: color,
                    fillColor: color,
                    fillOpacity: 0.1
                });
                message += '</div>';
                var infowindow = new BMap.InfoWindow(message, {
                    width : 300,     // 信息窗口宽度
                    height: 150,     // 信息窗口高度
                    title : infoTitle , // 信息窗口标题
                });
                this.thermalCircles.push([circle, color, infowindow]);
                break;
            case 'pressure':
                if(!isOther){
                    infoTitle = this.pressureInfo[value][0];
                    message += this.pressureInfo[value][1];
                }
                else if(isOther){
                    infoTitle = '此距离处的最大超压值为：' + (parseFloat(value) * psi2atm).toFixed(2) + 'atm。';
                }
                if(opt == 'AirBurst_0'){
                    message += '使此压力影响范围最大的爆炸高度是：' + (psi.opt_height_for_psi_from_interpolate(this.W, parseFloat(value))[0] * feet2m).toFixed(2) + 'm。'
                }
                if(opt == 'AirBurst_1'){
                    message += extraInfo;
                }
                color = this.getGradientColor(type, parseFloat(value));
                circle = new BMap.Circle(p, r,{
                    strokeWeight: 1,
                    strokeColor: color,
                    fillColor: color,
                    fillOpacity: 0.1
                });
                message += '</div>';
                var infowindow = new BMap.InfoWindow(message, {
                    width : 300,     // 信息窗口宽度
                    height: 150,     // 信息窗口高度
                    title : infoTitle , // 信息窗口标题
                });
                this.pressureCircles.push([circle, color, infowindow]);
                break;
            case 'fireball':
                infoTitle = this.fireballInfo[0] + extraInfo;
                message += this.fireballInfo[1] + + (effects.minimum_height_for_negligible_fallout(this.W) * mile2m).toFixed(2) + 'm';
                color = this.getGradientColor(type, parseFloat(value));
                circle = new BMap.Circle(p, r,{
                    strokeWeight: 1,
                    strokeColor: color,
                    fillColor: color,
                    fillOpacity: 0.1
                });
                message += '</div>';
                var infowindow = new BMap.InfoWindow(message, {
                    width : 300,     // 信息窗口宽度
                    height: 120,     // 信息窗口高度
                    title : infoTitle , // 信息窗口标题
                });
                this.fireballCircle.push([circle, color, infowindow]);
                break;
        }
    }

    drawCircles(type){
        switch(type){
            case 'dose':
                this.addCircleAndListenter(this.doseCircles, this.thermalCircles, this.pressureCircles, this.fireballCircle);
                break;
            case 'thermal':
                this.addCircleAndListenter(this.thermalCircles, this.doseCircles, this.pressureCircles, this.fireballCircle)
                break;
            case 'pressure':
                this.addCircleAndListenter(this.pressureCircles, this.doseCircles, this.thermalCircles, this.fireballCircle);
                break;
            case 'fireball':
                this.addCircleAndListenter(this.fireballCircle, this.doseCircles, this.thermalCircles, this.pressureCircles);
                break;
        }
    }

    addCircleAndListenter(crs, crs1, crs2, crs3){
        for(let i = 0; i < crs.length; i ++){
            let c = crs[i][0];
            let infowindow = crs[i][2];
            let that = this;
            // console.log('c', c);
            // console.log('crs', crs);
            // console.log('infowindow', infowindow);
            map.addOverlay(c);
            // 鼠标进入圆内事件 
            c.addEventListener('mouseover', function(){
                map.openInfoWindow(infowindow, mouseposi);
                // 改变当前进入的圆的颜色和线粗
                c.setStrokeColor('rgb(255, 255, 255)');
                c.setStrokeWeight(2);
                // 还原其他圆的颜色和线粗
                for(let j = 0; j < crs.length; j ++){
                    if(j != i){
                        crs[j][0].setStrokeColor(crs[j][1]);
                        crs[j][0].setStrokeWeight(1);
                    }
                }
                that.restoreCircles(crs1);
                that.restoreCircles(crs2);
                that.restoreCircles(crs3);
            })
            // 鼠标离开圆内事件
            c.addEventListener('mouseout', function(){
                map.closeInfoWindow();
                c.setStrokeColor(crs[i][1]);
                c.setStrokeWeight(1);
            })
        }
    }

    restoreCircles(crs){
        for(let i = 0; i < crs.length; i++){
            crs[i][0].setStrokeColor(crs[i][1]);
            crs[i][0].setStrokeWeight(1);
        }
    }

    getPolygon(points, doserate){
        let polygon;
        let color;
        let infowindow;
        color = this.getGradientColor('fallout', doserate);
        polygon = new BMap.Polygon(points, {
            strokeColor: color,
            strokeWeight: 1,
            fillColor: color,
            fillOpacity: 0.5
        });
        infowindow = new BMap.InfoWindow('剂量率为：'+doserate/100+'Gy/h', {
            width : 100,     // 信息窗口宽度
            height: 30,     // 信息窗口高度
            offset: new BMap.Size(5, 5)
        });
        this.falloutPolygons.push([polygon, color, infowindow]);
    }

    drawPolygon(){
        for(let i = 0; i < this.falloutPolygons.length; i ++){
            let p = this.falloutPolygons[i][0];
            let color = this.falloutPolygons[i][1];
            let infowindow = this.falloutPolygons[i][2];
            let that = this;
            map.addOverlay(p);
            // 鼠标进入多边形内事件
            p.addEventListener('mouseover', function(){
                map.openInfoWindow(infowindow, mouseposi);
                // 改变当前多边形颜色及线宽
                p.setStrokeColor('rgb(255, 255, 255)');
                p.setStrokeWeight(2);
                // 还原其他多边形的颜色和线粗
                for(let j = 0; j < that.falloutPolygons.length; j++){
                    if(j != i){
                        that.falloutPolygons[j][0].setStrokeColor(that.falloutPolygons[j][1]);
                        that.falloutPolygons[j][0].setStrokeWeight(1);
                    }
                }
                // 还原圆的颜色和线粗
                that.restoreCircles(that.doseCircles);
                that.restoreCircles(that.thermalCircles);
                that.restoreCircles(that.pressureCircles);
                that.restoreCircles(that.fireballCircle);
            })
            // 鼠标离开多边形内事件
            p.addEventListener('mouseout', function(){
                map.closeInfoWindow();
                p.setStrokeColor(color);
                p.setStrokeWeight(1);
            })
        }
    }

    getGradientColor(type, value){
        let ratio;
        switch(type){
            // 绿色渐变
            case 'dose':
                ratio = (value - 100) / (5000 - 100);
                if(debug) console.log('g:', 150 + ratio * (225 - 150), 'ratio:', ratio)
                return 'rgb(0,' + (150 + ratio * (225 - 150)) + ', 0)';
            // 红色渐变
            case 'thermal':
                ratio = (value - 1) / (14 - 1);
                if(debug) console.log('r:', 100 + ratio * (200 - 100), 'ratio:', ratio)
                return 'rgb(' + (100 + ratio * (200 - 100)) + ', 0, 0)';
            // 蓝色渐变
            case 'pressure':
                ratio = (value - 1) / (3000 - 1);
                return 'rgb(0, 0,' + (100 + ratio * (225 - 100)) + ')';
            // 深红色
            case 'fireball':
                return '#FF6347';
            // 黄色渐变
            case 'fallout':
                ratio = (value - 1) / (10000 - 1);
                return 'rgb(' + (255 - ratio * 255) + ',' + (128 - ratio * 128) + ', 50)';
        }
    }
    
    show(type, toshow){
        switch(type){
            case 'dose':
                this.cir_or_polygon_show(this.doseCircles, toshow);
                break;
            case 'thermal':
                this.cir_or_polygon_show(this.thermalCircles, toshow);
                break;
            case 'pressure':
                this.cir_or_polygon_show(this.pressureCircles, toshow);
                break;
            case 'fallout':
                this.cir_or_polygon_show(this.falloutPolygons, toshow);
                break;
        }
    }

    cir_or_polygon_show(list, toshow){
        if(toshow){
            for(let i = 0; i < list.length; i++){
                list[i][0].show();
            }
        }
        else{
            for(let i = 0; i < list.length; i++){
                list[i][0].hide();
            }
        }
    }
}